
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include <gio/gio.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include "sqlite3.h"
/**
**/
int sql_callback(void *ptr, int n_column, char **column_value, char **column_name)
{
  int rc = 0, i;
  xmlNodePtr root_node = NULL, node = NULL;
  xmlAttrPtr attr;

  if (n_column == 0) {
    printf("sql: column is 0\n");
    rc = 1;
    goto err;
  }
  if (ptr) {
    root_node = ptr;
    node = xmlNewChild (root_node, NULL, BAD_CAST "child", NULL);
    for (i = 0; i < n_column; i++) {
      if (column_value[i]) {
        if (strlen (column_value[i]) > 0) {
          attr = xmlHasProp (node, BAD_CAST column_name[i]);
          if (!attr)
            xmlNewProp (node, BAD_CAST column_name[i], BAD_CAST column_value[i]);
        }
      }
    }
  }
// DEBUG("array:%s", json_object_get_string(obj));
err:
  return rc;
}
void *sql_exec(void *sql, const char *statement)
{
  int rc = 0;
  char *errmsg = NULL;
  gpointer res = NULL;
  xmlNodePtr root = NULL;
  xmlBufferPtr xmlbuf = NULL;

  root = xmlNewNode (NULL, BAD_CAST "root");
  rc = sqlite3_exec(sql, statement, sql_callback, root, &errmsg);
  errno = 0;
  if (rc != SQLITE_OK)
  {
    errno = rc;
    g_warning("SELECT:%s:%s:%d\n", statement, errmsg, rc);
    res = g_strdup(sqlite3_errmsg(sql));
    goto out;
  } else {
    g_debug("SELECT:%s", statement);
    xmlbuf = xmlBufferCreate ();
    rc = xmlNodeDump (xmlbuf, NULL, root, 0, 0);
    if (rc == -1) {
      g_warning ("xmlnodedump error\n");
      goto out;
    }
    res = g_strdup ((char *)xmlbuf->content);
  }
out:
  if (xmlbuf)
    xmlBufferFree (xmlbuf);
  if (root)
    xmlFreeNode (root);
  return res;
}
void *sql_exec_plus(void *sql, const char *statement, const char *name)
{
  int rc = 0;
  char *errmsg = NULL;
  gpointer res = NULL;
  xmlNodePtr root = NULL;
  xmlBufferPtr xmlbuf = NULL;

  root = xmlNewNode (NULL, BAD_CAST name);
  rc = sqlite3_exec(sql, statement, sql_callback, root, &errmsg);
  errno = 0;
  if (rc != SQLITE_OK)
  {
    errno = rc;
    g_warning("SELECT:%s:%s:%d\n", statement, errmsg, rc);
    res = g_strdup(sqlite3_errmsg(sql));
    goto out;
  } else {
    g_debug("SELECT:%s", statement);
    xmlbuf = xmlBufferCreate ();
    rc = xmlNodeDump (xmlbuf, NULL, root, 0, 0);
    if (rc == -1) {
      g_warning ("xmlnodedump error\n");
      goto out;
    }
    res = g_strdup ((char *)xmlbuf->content);
  }
out:
  if (xmlbuf)
    xmlBufferFree (xmlbuf);
  if (root)
    xmlFreeNode (root);
  return res;
}
int sql_count_callback(void *ptr, int n_column, char **column_value,
                char **column_name)
{
  int rc = 0, *sum = NULL;

  g_debug("L%d f-%s", __LINE__, __func__);
  if (n_column == 0) {
    printf("sql: column is 0\n");
    rc = 1;
    goto err;
  }
  if (ptr) {
    sum = ptr;
    *sum = *sum + 1;
  } else {
    g_error("NO PTR\n");
  }
err:
      return rc;
}
int sql_exec_count(void *sql, const char *statement)
{
  int rc = 0, count = 0;
  char *errmsg = NULL;

  g_debug("L%d f-%s statement:%s", __LINE__, __func__, statement);
  rc = sqlite3_exec(sql, statement, sql_count_callback, &count, &errmsg);
  if (rc != SQLITE_OK) {
    g_warning("L%d f-%s rc:%d %s", __LINE__, __func__, rc, errmsg);
    rc = -1;
    goto err;
  }
  rc = count;
err:
  return rc;
}

int sql_exist(void *sql, const char *table, const char *field, const char *value)
{
  char statement[1024] = {0};
  int rc = 0;

  snprintf(statement, sizeof(statement),
      "select 1 from '%s' where %s='%s' limit 1;",
      table, field, value);
  rc = sql_exec_count(sql, statement);

  return rc;
}
int sql_int_callback(void *ptr, int n_column,
    char **column_value, char **column_name)
{
  int rc = 0;

  if (n_column == 0) {
    rc = -1;
    goto err;
  }
  if (ptr) {
    rc = atoi (column_value[0]);
    *(int *)ptr = rc;
  }
err:
  return rc;
}
int sql_int_exec(void *sql, const char *statement)
{
  int rc = 0, res = 0;
  char *errmsg = NULL;

  rc = sqlite3_exec(sql, statement, sql_callback, &res, &errmsg);
  errno = 0;
  if (rc != SQLITE_OK)
  {
    errno = rc;
    g_warning("SELECT:%s:%s:%d\n", statement, errmsg, rc);
    res = -1;
    goto out;
  }
out:
  return res;
}
int sql_int_list_callback(void *ptr, int n_column,
    char **column_value, char **column_name)
{
  int rc = 0;
  GList *l = NULL;

  l = *(GList **)ptr;
  if (n_column == 0) {
    rc = -1;
    goto err;
  }
  if (ptr) {
    rc = atoi (column_value[0]);
    l = g_list_append (l, GINT_TO_POINTER(rc));
  }
  *(GList **)ptr = l;
err:
  return rc;
}
void *sql_int_list_exec(void *sql, const char *statement)
{
  int rc = 0;
  char *errmsg = NULL;
  GList *res = NULL;

  rc = sqlite3_exec(sql, statement, sql_callback, &res, &errmsg);
  errno = 0;
  if (rc != SQLITE_OK)
  {
    errno = rc;
    g_warning("SELECT:%s:%s:%d\n", statement, errmsg, rc);
    res = NULL;
    goto out;
  }
out:
  return res;
}
